#include <bits/stdc++.h>
#define IOS ios_base::sync_with_stdio(0), cin.tie(0), cout.tie(0)
#define endl "\n"
using namespace std;
typedef long long ll;
int n, m, l, v, id;
struct car
{
    int d, v, a;
};
vector<car> cars;
vector<int> dtct;
unordered_map<int, vector<int> > ans;
vector<pair<int, pair<int, int> > > fast;
int cnt[100010];
bool vis[100010];
car tmp;
int fnd(int x)
{
    int l = 0, r = m - 1, ret = -1;
    while(l <= r)
    {
        int mid = (l + r) >> 1;
        if(dtct[mid] >= x) ret = mid, r = mid - 1;
        else l = mid + 1;
    }
    return ret;
}
int fnd2(int x)
{
    int l = 0, r = m - 1, ret = -1;
    while(l <= r)
    {
        int mid = (l + r) >> 1;
        if(dtct[mid] < x) ret = mid, l = mid + 1;
        else r = mid - 1;
    }
    return ret;
}
bool cmp(pair<int, int> x, pair<int, int> y)
{
    if(x.first != y.first) return x.first < y.first;
    return x.second > y.second;
}
void solve()
{
    bool case1 = true, case2 = true;
    memset(cnt, 0, sizeof cnt), memset(vis, 0, sizeof vis);
    cars.clear(), dtct.clear(), fast.clear(), ans.clear();
    cin >> n >> m >> l >> v;
    id = 0;
    for(int i = 0; i < n; i ++) cin >> tmp.d >> tmp.v >> tmp.a, cars.push_back(tmp);
    for(int i = 0; i < m; i ++) cin >> tmp.d, dtct.push_back(tmp.d);
    sort(dtct.begin(), dtct.end());
    for(int i = 0; i < cars.size(); i ++)
    {
        car now = cars[i];
        if(now.a == 0 && now.v > v && fnd(now.d) != -1) fast.push_back({i, {fnd(now.d), m - 1}});
        else if(now.a > 0)
        {
            int dis = v * v - now.v * now.v;
            dis = dis / (2 * now.a) + 1;
            dis += now.d;
            if(fnd(dis) != -1) fast.push_back({i, {fnd(dis), m - 1}});
            case1 = false;
        }
        else if(now.a < 0 && now.v > v)
        {
            int dis = now.v * now.v - v * v;
            if(dis % (-2 * now.a) == 0) dis = dis / (-2 * now.a);
            else dis = dis / (-2 * now.a) + 1;
            dis += now.d;
            if(fnd2(dis) != -1 && fnd2(dis) >= fnd(now.d)) fast.push_back({i, {fnd(now.d), fnd2(dis)}});
            case1 = false, case2 = false;
        }
    }
    if(case1)
    {
        if(fast.size()) cout << fast.size() << " "  << m - 1 << endl;
        else cout << fast.size() << " "  << m << endl;
        return;
    }
    else if(case2)
    {
        if(fast.size()) cout << fast.size() << " "  << m - 1 << endl;
        else cout << fast.size() << " "  << m << endl;
        return;
    }
    sort(fast.begin(), fast.end());
    int c = 0;
    set<int> ids;
    for(int i = 0; i < fast.size(); i ++) for(int j = fast[i].second.first; j <= fast[i].second.second; j ++) ans[j].push_back(i), cnt[i] ++, ids.insert(j);
    vector<int> rids;
    for(auto it : ids) rids.push_back(it);
    for(int i = 0; i < fast.size(); i ++)
    {
        bool f = false;
        for(int tt = 0; tt < rids.size(); tt ++)
        {
            int j = rids[tt];
            bool fl = true;
            if(vis[j]) continue;
            for(int k = 0; k < ans[j].size(); k ++)
            {
                if(cnt[ans[j][k]] <= 1)
                {
                    fl = false;
                    break;
                }
            }
            if(fl)
            {
                for(int k = 0; k < ans[j].size(); k ++) cnt[ans[j][k]] --;
                c ++;
                vis[j] = true;
                f = true;
                break;
            }
        }
        if(!f) break;
    }
    cout << fast.size() << " " << c + (m - ids.size()) << endl;
    return;
}
int main()
{
    IOS;
    freopen("detect.in", "r", stdin);
    freopen("detect.out", "w", stdout);
    int T;
    cin >> T;
    while(T --) solve();
    return 0;
}
/*
5 5 15 3
0 3 0
12 4 0
1 1 4
5 5 ‐2
6 4 ‐4
2 5 8 9 15
*/
